package com.ikingtech.framework.sdk.context.security;

import com.ikingtech.framework.sdk.enums.authenticate.SignEndpointTypeEnum;
import com.ikingtech.framework.sdk.utils.Tools;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.Serial;
import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static com.ikingtech.framework.sdk.context.constant.SecurityConstants.GLOBAL_TOKEN;
import static com.ikingtech.framework.sdk.context.constant.SecurityConstants.HEADER_INNER_IDENTITY;

/**
 * @author tie yan
 */
@Data
public class Identity implements Serializable {

    @Serial
    private static final long serialVersionUID = -928777645979007550L;

    public static final String ADMIN_USER_ID = "00000000";

    public static final String ADMIN_USER_NAME = "admin";

    public static final String ADMIN_NAME = "系统管理员";

    /**
     * 用户id
     */
    private String id;

    /**
     * 用户账户
     */
    private String username;

    /**
     * 密码（密文）
     */
    private String password;

    /**
     * 密码是否过期
     */
    private Boolean passwordExpired;

    /**
     * 密码修改时间
     */
    private LocalDateTime passwordModifyTime;

    /**
     * 用户昵称
     */
    private String name;

    /**
     * 头像
     */
    private String avatar;

    /**
     * 手机号
     */
    private String phone;

    /**
     * 是否锁定
     */
    private Boolean locked;

    /**
     * 锁类型
     */
    private String lockType;

    /**
     * 是否通过了身份验证
     */
    private Boolean authenticated;

    /**
     * 失败原因
     */
    private String cause;

    /**
     * 数据权限
     */
    private List<String> dataScopeCodes;

    /**
     * token
     */
    private String token;

    /**
     * 语言环境
     */
    private String lang;

    /**
     * 租户code
     */
    private String tenantCode;

    /**
     * 菜单id
     */
    private String menuId;

    /**
     * 客户端类型
     */
    private String endpoint;

    /**
     * 用户扩展信息
     */
    private Map<String, Object> extensions;

    /**
     * 请求的扩展头
     */
    private Map<String, Object> extensionHeaders;

    /**
     * 用户类别标识集合
     */
    private List<String> categoryCodes;

    /**
     * 用户登录的域
     */
    private String domainCode;

    /**
     * 当前应用
     */
    private String appCode;

    public static Identity defaultUser() {
        Identity identity = new Identity();
        identity.setId("99999999");
        identity.setUsername("unknown");
        identity.setName("未知用户");
        identity.setLang(Locale.SIMPLIFIED_CHINESE.toLanguageTag());
        return identity;
    }

    public static Identity admin() {
        Identity identity = new Identity();
        identity.setId(ADMIN_USER_ID);
        identity.setUsername(ADMIN_USER_NAME);
        identity.setName(ADMIN_NAME);
        identity.setDataScopeCodes(new ArrayList<>());
        identity.setLang(Locale.SIMPLIFIED_CHINESE.toLanguageTag());
        identity.setToken(GLOBAL_TOKEN);
        identity.setEndpoint(SignEndpointTypeEnum.PC.name());
        return identity;
    }

    public static String inner() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null == attributes) {
            //内部调用设置默认用户信息
            return URLEncoder.encode(Tools.Json.toJsonStr(Identity.defaultUser()), Charset.defaultCharset());
        }
        HttpServletRequest request = attributes.getRequest();
        String identityStr = request.getHeader(HEADER_INNER_IDENTITY);
        if (Tools.Str.isBlank(identityStr)) {
            //内部调用设置默认用户信息
            return URLEncoder.encode(Tools.Json.toJsonStr(Identity.defaultUser()), Charset.defaultCharset());
        }
        return identityStr;
    }
}
